package com.github.yoojia.mqtt.util;

import com.parkingwang.lang.Consumer;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Yoojia Chen (yoojiachen@gmail.com)
 * @since 1.0.0
 */
public abstract class MapCached<K, V> {

    private final Map<K, V> mCached;

    protected MapCached(int initCapacity) {
        mCached = new ConcurrentHashMap<>(initCapacity);
    }

    public V getOrNew(K key) {
        V v;
        if ((v = mCached.get(key)) == null) {
            V newValue;
            if ((newValue = newByKey(key)) != null) {
                mCached.put(key, newValue);
                return newValue;
            }
        }
        return v;
    }

    public V getPresent(K key) {
        return mCached.get(key);
    }

    public Collection<V> values() {
        return mCached.values();
    }

    public boolean containsKey(K key) {
        return mCached.containsKey(key);
    }

    protected abstract V newByKey(K key);

    public void ifPresent(K key, Consumer<V> consumer) {
        if (containsKey(key)) {
            consumer.call(getPresent(key));
        }
    }
}
